const mysql = require('../../mysql')
const dateformat = require('dateformat') // https://github.com/felixge/node-dateformat
const randomHelper = require('./randomHelper')

/**
 * 根据条件查询设备
 * @param where
 * @returns {Promise<void>}
 */
async function queryDevs(where) {
  const tsps = {} // 缓存有设备的车厂 [thirdPartyId]: tsp

  const devs = await T_DEVICES.query(where)

  for (let i = 0; i < devs.length; i++) {
    const dev = devs[i]
    if (tsps[dev.thirdPartyId]) {
      // 已经缓存, 则使用缓存的信息
      devs[i] = Object.assign({}, dev, tsps[dev.thirdPartyId])
      continue
    }
    // 没缓存则查数据表
    const tsp = await T_TSPS.query(`thirdPartyId = "${dev.thirdPartyId}"`)
    // 更新数据并缓存查到的数据
    devs[i] = Object.assign({}, dev, tsp)
    tsps[tsp.thirdPartyId] = tsp
  }

  return devs
}

/**
 * 在授权的时候插入车辆信息, 当前不支持同一个车厂多个车型prodId的场景, 默认取第一个车厂
 */
async function insertDev(params) {
  // 组装devices中的services, 是一个对象的json字符串格式，对象包含 ts、sid、data
  const services = []
  const tsp = await T_TSPS.query(`thirdPartyId = "${params.thirdPartyId}"`)
  if (tsp && tsp.length <= 0) {
    throw new Error(`根据三方ID： ${params.thirdPartyId} 查询表 ${T_TSPS.tableName} 未找到关联数据, 请手动插入.`)
  }
  const { services: devServices, tag, devName, prodId } = tsp[0]
  const vin = randomHelper.vin(tag)

  for (const service of (JSON.parse(devServices) || [])) {
    const sid = service.sid

    const datas = await T_SID_DATA.queryDataBySid(sid)
    let { data } = await datas && datas.length > 0 && datas[0]
    data = data ? JSON.parse(data) : {}
    // 特殊处理staticInfo这个sid
    if (sid === 'staticInfo') {
      data = Object.assign(data, { 'infoVin': vin })
    }
    services.push({
      ts: dateformat(new Date(), `UTC:yyyymmdd'T'HHMMssl'Z'`),
      sid,
      data // 增加在线编辑
    })
  }

  return T_DEVICES.insert(Object.assign({}, params, {
    udid: vin, // 保证每个车厂的TAG不一样
    serviceData: JSON.stringify(services),
    thirdPartyDevId: vin,
    devName,
    prodId
  }))
}

const T_DEVICES = {
  tableName: 't_devices', // tableName 这里约定必须是对象名的全小写
  query(where) {
    return mysql.query(T_DEVICES.tableName, where)
  },
  update(action, where) {
    return mysql.update(T_DEVICES.tableName, action, where)
  },
  insert(params) {
    return mysql.insert(T_DEVICES.tableName, params)
  },
  delete(where) {
    return mysql.del(T_DEVICES.tableName, where)
  }
}

const T_SID_DATA = {
  tableName: 't_sid_data',
  query(where) {
    return mysql.query(T_SID_DATA.tableName, where)
  },
  queryDataBySid(sid) {
    return mysql.query(T_SID_DATA.tableName, `sid = "${sid}"`)
  },
  insert(sid, data) {
    return mysql.insert(T_SID_DATA.tableName, { sid, data })
  },
  update(sid, data) {
    return mysql.update(T_SID_DATA.tableName, `data = ${data}`, `sid = "${sid}"`)
  }
}

const T_TSPS = {
  tableName: 't_tsps',
  query(where) {
    return mysql.query(T_TSPS.tableName, where)
  }
}

const T_TSP_CONFIG = {
  tableName: 't_tsp_config',
  query(where) {
    return mysql.query(T_TSP_CONFIG.tableName, where)
  }
}

module.exports = { queryDevs, insertDev, T_DEVICES, T_TSPS, T_SID_DATA, T_TSP_CONFIG }
